<template>
  <div class="app-container">
    <div class="chat-layout">
      <!-- 聊天历史侧边栏 -->
      <div class="history-sidebar" :class="{ 'collapsed': sidebarCollapsed }">
        <div class="sidebar-header">
          <h3>聊天历史</h3>
          <div class="sidebar-header-actions">
            <el-popconfirm
              title="确定清空所有对话记录吗？"
              @confirm="handleClearAllDialogues"
            >
              <el-button slot="reference" type="text" size="mini" icon="el-icon-delete" class="clear-btn" title="清空所有对话"></el-button>
            </el-popconfirm>
          </div>
        </div>

        <div class="sidebar-new-chat" @click="createNewDialogue">
          <i class="el-icon-plus"></i>
          <span>新建对话</span>
        </div>

        <div class="sidebar-content">
          <div v-if="dialogueList.length === 0" class="empty-history">
            <i class="el-icon-chat-dot-square"></i>
            <span>暂无聊天记录</span>
          </div>
          <div
            v-for="item in dialogueList"
            :key="item.dialogueId"
            class="history-item"
            :class="{ 'active': dialogueId === item.dialogueId }"
          >
            <div class="history-item-content" @click="switchDialogue(item.dialogueId)">
              <div class="history-item-title">{{ formatHistoryTitle(item.firstContent) }}</div>
              <div class="history-item-time">{{ formatTime(item.createTime) }}</div>
            </div>
            <div class="history-item-actions" v-show="dialogueId !== item.dialogueId">
              <el-popconfirm
                title="确定删除此对话吗？"
                @confirm="handleDeleteDialogue(item.dialogueId)"
              >
                <el-button slot="reference" type="text" size="mini" icon="el-icon-delete" class="delete-btn"></el-button>
              </el-popconfirm>
            </div>
          </div>
        </div>
      </div>

      <!-- 主聊天区域 -->
      <div class="chat-container">
        <div class="chat-header">
          <el-button
            type="text"
            :icon="sidebarCollapsed ? 'el-icon-s-unfold' : 'el-icon-s-fold'"
            @click="toggleSidebar"
            class="toggle-btn"
          ></el-button>
          <h2>AI聊天室</h2>
          <div class="header-actions">
            <div class="remaining-count" :class="{'warning-count': remainingCount < 10, 'danger-count': remainingCount < 5}">
              <i class="el-icon-chat-dot-square"></i>
              剩余次数 <span>{{ remainingCount }}</span>
            </div>
          </div>
        </div>

        <div class="chat-content" ref="chatContent">
          <div v-if="!dialogueId || showWelcome" class="welcome-container">
            <div class="welcome-title">您好，欢迎使用AI聊天系统</div>
            <div class="welcome-tips">我是一名智能聊天AI机器人，能回答各种问题，提供专业解答</div>
            <div class="quick-questions">
              <div class="quick-title">您可以尝试这些问题：</div>
              <div
                v-for="item in quickQuestions"
                :key="item.id"
                class="quick-item"
                @click="useQuickQuestion(item.tips)"
              >
                {{ item.tips }}
              </div>
            </div>
          </div>

          <div v-else class="messages-container">
            <div
              v-for="(message, index) in chatMessages"
              :key="index"
              :class="['message', message.role === 'user' ? 'user-message' : 'ai-message']"
            >
              <div class="message-avatar">
                <img :src="message.role === 'user' ? userAvatar : aiAvatar" alt="avatar">
              </div>
              <div class="message-content">
                <div v-if="message.role === 'assistant'" v-html="formatMessage(message.content)"></div>
                <div v-else>{{ message.content }}</div>
                <div v-if="message.role === 'assistant'" class="message-actions">
                  <el-button type="text" icon="el-icon-document-copy" class="copy-btn" @click="copyMessage(message.content)" title="复制内容"></el-button>
                </div>
              </div>
            </div>

            <!-- 等待状态动画 -->
            <div v-if="isTyping" class="message ai-message">
              <div class="message-avatar">
                <img :src="aiAvatar" alt="avatar">
              </div>
              <div class="message-content">
                <div v-if="currentAnswer" v-html="formatMessage(currentAnswer)"></div>
                <div v-else class="typing-indicator">
                  <span></span>
                  <span></span>
                  <span></span>
                </div>
                <div v-if="currentAnswer" class="message-actions">
                  <el-button type="text" icon="el-icon-document-copy" class="copy-btn" @click="copyMessage(currentAnswer)" title="复制内容"></el-button>
                </div>
              </div>
            </div>
          </div>
        </div>

        <div class="chat-input">
          <div class="prompt-input">
            <el-input
              type="text"
              placeholder="可选：输入提示词引导AI回答方向..."
              v-model="prompt"
              :disabled="!isThisChatOver || !dialogueId"
              class="prompt-field"
            >
              <template slot="prepend">
                <span class="prompt-label">提示词</span>
              </template>
              <template slot="append">
                <el-dropdown @command="selectCommonPrompt" trigger="click">
                  <span class="el-dropdown-link">
                    快捷选择<i class="el-icon-arrow-down el-icon--right"></i>
                  </span>
                  <el-dropdown-menu slot="dropdown">
                    <el-dropdown-item v-for="(item, index) in commonPrompts" :key="index" :command="item">{{item}}</el-dropdown-item>
                    <el-dropdown-item divided command="clear">清空提示词</el-dropdown-item>
                  </el-dropdown-menu>
                </el-dropdown>
                <el-popover
                  placement="top"
                  width="300"
                  trigger="hover">
                  <div class="prompt-help">
                    <p>提示词用于引导AI回答的方向和风格，例如：</p>
                    <ul>
                      <li>使用技术专家的口吻回答</li>
                      <li>像老师一样详细解释</li>
                      <li>以幽默风趣的方式回应</li>
                      <li>用中文回复所有问题</li>
                    </ul>
                  </div>
                  <i slot="reference" class="el-icon-question"></i>
                </el-popover>
              </template>
            </el-input>
          </div>
          <el-input
            type="textarea"
            :rows="3"
            placeholder="请输入您的问题..."
            v-model="inputMessage"
            :disabled="!isThisChatOver || !dialogueId"
            @keyup.ctrl.enter.native="sendMessage"
          ></el-input>
          <div class="input-actions">
            <div class="input-tips">按Ctrl+Enter发送</div>
            <el-button
              type="primary"
              :loading="!isThisChatOver"
              :disabled="!dialogueId || !inputMessage.trim()"
              @click="sendMessage"
            >
              发送
            </el-button>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>

<script>
import { createDialogue, sendChatMessage, getChatHistory, listDialogues, deleteDialogue, getChatRemainingCount } from "@/api/ai/chatRoom";
import { marked } from 'marked';
import hljs from 'highlight.js';
import 'highlight.js/styles/github.css';
import websocketClient from "@/utils/websocket";

export default {
  name: "ChatRoom",
  data() {
    return {
      dialogueId: null,
      inputMessage: "",
      prompt: "",
      chatMessages: [],
      isTyping: false,
      isThisChatOver: true,
      currentAnswer: "",
      socketStatus: "closed",
      overFlag: "THIS_CHAT_OVER",
      userAvatar: "",
      aiAvatar: require("@/assets/logo/logo.png"),
      quickQuestions: [
        { id: 1, tips: "请用Java帮我写个简单的冒泡排序" },
        { id: 2, tips: "如何提高编程效率" },
        { id: 3, tips: "简述Spring框架的核心特性" },
        { id: 4, tips: "人工智能的发展历程是什么" },
      ],
      newMessageQueue: [], // 消息队列
      dialogueList: [], // 对话历史列表
      sidebarCollapsed: false, // 侧边栏状态
      typingSpeed: 15, // 打字机效果速度(ms)，降低速度使效果更明显
      typingTimer: null, // 打字机定时器
      typingInProgress: false, // 是否正在进行打字效果
      pendingCompletion: false, // 是否有等待完成的对话
      lastMessageTime: null, // 最后接收消息的时间
      wsPath: process.env.VUE_APP_WS_PATH || '/ws/ma/chat/', // WebSocket路径从环境变量获取
      directConnect: process.env.VUE_APP_WS_DIRECT_CONNECT !== 'false', // 从环境变量获取连接模式
      showWelcome: true, // 新增的showWelcome属性
      remainingCount: 0, // 聊天剩余次数
      defaultAvatar: require("@/assets/logo/logo.png"), // 默认头像
      commonPrompts: [ // 常用提示词列表
        "用简洁专业的方式回答",
        "像技术专家一样解释",
        "用中文回答所有问题",
        "以教学的方式详细讲解",
        "提供具体的代码示例"
      ]
    };
  },
  created() {
    this.initMarked();
    this.checkUserLogin();
  },
  mounted() {
    if (this.isLoggedIn) {
      console.log("用户已登录，准备连接WebSocket");
      // 设置用户头像
      this.setUserAvatar();

      // 设置WebSocket消息处理回调
      websocketClient.onMessage(this.handleWebSocketMessage);
      websocketClient.onStatusChange(this.handleWebSocketStatusChange);

      // 初始化WebSocket连接模式
      this.initWebSocketMode();

      // 立即连接WebSocket
      this.connectWebSocket();

      // 监听页面可见性变化，在页面恢复可见时重连
      document.addEventListener('visibilitychange', this.handleVisibilityChange);

      // 加载对话列表
      this.loadDialogueList();

      // 获取剩余聊天次数
      this.loadRemainingCount();
    }
  },
  beforeDestroy() {
    console.log("组件销毁，关闭WebSocket连接");
    // 清除所有定时器
    this.clearTypingTimer();

    // 关闭WebSocket连接
    websocketClient.close();

    // 移除WebSocket回调
    websocketClient.removeMessageCallback(this.handleWebSocketMessage);
    websocketClient.removeStatusCallback(this.handleWebSocketStatusChange);

    // 移除事件监听器
    document.removeEventListener('visibilitychange', this.handleVisibilityChange);
  },
  computed: {
    isLoggedIn() {
      return this.$store.getters.token != null && this.$store.getters.token !== '';
    }
  },
  methods: {
    // 初始化WebSocket连接模式
    initWebSocketMode() {
      // 直接使用环境变量中的配置
      websocketClient.directConnect = this.directConnect;
      console.log("初始化WebSocket连接模式:", this.directConnect ? "直连模式" : "代理模式");
    },

    // 格式化聊天历史的标题
    formatHistoryTitle(content) {
      if (!content) return '新对话';

      // 移除HTML标签
      let plainText = content.replace(/<[^>]+>/g, '');

      // 截取前20个字符，如果超过则添加省略号
      if (plainText.length > 20) {
        return plainText.substring(0, 20) + '...';
      }

      return plainText;
    },

    // 清除打字机定时器
    clearTypingTimer() {
      if (this.typingTimer) {
        clearTimeout(this.typingTimer);
        this.typingTimer = null;
      }
    },

    // 打字机效果函数
    typeWriterEffect(fullText) {
      // 清除之前的定时器
      this.clearTypingTimer();

      let displayText = '';
      let index = 0;

      const type = () => {
        if (index < fullText.length) {
          displayText += fullText.charAt(index);
          this.currentAnswer = displayText;
          index++;
          this.typingTimer = setTimeout(type, this.typingSpeed);
          this.scrollToBottom();
        } else {
          // 完成打字
          this.currentAnswer = fullText;
        }
      };

      // 开始打字效果
      type();
    },

    initMarked() {
      // 设置marked配置，支持代码高亮
      const renderer = new marked.Renderer();

      // 自定义代码块渲染
      renderer.code = (code, language) => {
        const validLanguage = hljs.getLanguage(language) ? language : 'plaintext';
        const highlightedCode = hljs.highlight(validLanguage, code).value;

        // 生成唯一ID用于识别代码块
        const codeId = 'code-' + Date.now() + '-' + Math.floor(Math.random() * 1000);

        // 添加代码语言标签和复制按钮，保存代码内容到data属性
        return `
          <div class="code-block-wrapper">
            <div class="code-block-header">
              <span class="code-language">${validLanguage}</span>
              <button class="code-copy-btn" data-code-id="${codeId}">复制代码</button>
            </div>
            <div class="code-container">
              <pre class="hljs"><code class="language-${validLanguage}" id="${codeId}">${highlightedCode}</code></pre>
            </div>
          </div>
        `;
      };

      // 设置marked配置
      marked.setOptions({
        renderer: renderer,
        highlight: function(code, language) {
          const validLanguage = hljs.getLanguage(language) ? language : 'plaintext';
          return hljs.highlight(validLanguage, code).value;
        },
        gfm: true,
        breaks: true,
        pedantic: false,
        smartLists: true,
        smartypants: false,
        xhtml: false
      });
    },

    formatMessage(content) {
      if (!content) return '';
      const html = marked.parse(content);

      // 在nextTick添加复制按钮事件监听
      this.$nextTick(() => {
        this.setupCodeCopyButtons();
      });

      return html;
    },

    // 设置代码复制按钮的事件监听
    setupCodeCopyButtons() {
      const copyButtons = document.querySelectorAll('.code-copy-btn');
      copyButtons.forEach(button => {
        // 移除旧的事件监听器
        button.removeEventListener('click', this.handleCodeCopy);
        // 添加新的事件监听器
        button.addEventListener('click', this.handleCodeCopy);
      });
    },

    // 处理代码复制事件
    handleCodeCopy(event) {
      const button = event.target;
      const codeId = button.getAttribute('data-code-id');
      const codeElement = document.getElementById(codeId);

      if (codeElement) {
        // 获取纯文本内容(不含HTML标签)
        const code = codeElement.textContent || '';

        // 使用Clipboard API复制文本
        navigator.clipboard.writeText(code)
          .then(() => {
            // 复制成功
            button.textContent = '已复制';
            setTimeout(() => {
              button.textContent = '复制代码';
            }, 1500);

            this.$message({
              message: "代码已复制到剪贴板",
              type: "success",
              duration: 1500
            });
          })
          .catch(err => {
            // 复制失败
            console.error('复制失败:', err);
            this.$message.error("复制失败，请手动复制");
          });
      }
    },

    // 处理页面可见性变化
    handleVisibilityChange() {
      if (document.visibilityState === 'visible') {
        console.log("页面恢复可见，检查WebSocket连接");
        // 检查WebSocket连接状态，如果连接已关闭或未连接，则重新连接
        if (websocketClient.getStatus() !== 'connected' &&
            websocketClient.getStatus() !== 'connecting') {
          console.log("WebSocket未连接或已关闭，尝试重新连接");
          this.connectWebSocket();
        } else {
          console.log("WebSocket连接正常，无需重连");
        }
      }
    },

    // 处理WebSocket状态变化
    handleWebSocketStatusChange(status) {
      console.log("WebSocket状态变化:", status);
      this.socketStatus = status;

      if (status === 'connected') {
        this.$message({
          message: "WebSocket连接成功",
          type: "success",
          duration: 2000
        });
      } else if (status === 'closed') {
        console.log("WebSocket连接已关闭");
      }
    },

    // 连接WebSocket
    connectWebSocket() {
      const token = this.$store.getters.token;
      if (!token) {
        this.$message.error("请先登录");
        return;
      }

      // 如果已连接或正在连接，则不重复连接
      if (websocketClient.getStatus() === 'connected' ||
          websocketClient.getStatus() === 'connecting') {
        console.log("WebSocket已连接或正在连接中，无需重复连接");
        return;
      }

      // 使用WebSocket客户端连接
      websocketClient.connect(token, this.wsPath);
    },

    // 处理WebSocket消息
    handleWebSocketMessage(message) {
      if (message) {
        if (message === this.overFlag) {
          // 对话结束
          console.log("收到对话结束标记");

          // 确保所有消息都已经处理完毕
          if (this.typingInProgress || (this.newMessageQueue && this.newMessageQueue.length > 0)) {
            // 如果还有消息在处理或队列中，设置一个标记，稍后结束
            this.pendingCompletion = true;
            return;
          }

          this.finishConversation();
        } else {
          // 处理流式响应
          this.isTyping = true;
          this.pendingCompletion = false;

          // 将新消息添加到消息队列
          if (!this.newMessageQueue) {
            this.newMessageQueue = [];
          }
          this.newMessageQueue.push(message);

          // 如果当前没有正在进行的打字效果，则开始显示
          if (!this.typingInProgress) {
            this.showNextMessage();
          }
        }
      }
    },

    // 结束对话的函数
    finishConversation() {
      this.isThisChatOver = true;
      this.isTyping = false;
      this.pendingCompletion = false;

      // 将AI回答添加到消息列表
      if (this.currentAnswer) {
        this.chatMessages.push({
          role: 'assistant',
          content: this.currentAnswer
        });
      }
      this.currentAnswer = "";
      this.scrollToBottom();
      // 刷新对话列表
      this.loadDialogueList();
      // 刷新剩余次数
      this.loadRemainingCount();
      
      // 注意：不清空prompt字段，允许用户继续使用相同的提示词
    },

    // 显示下一条消息
    showNextMessage() {
      if (this.newMessageQueue && this.newMessageQueue.length > 0) {
        const nextMessage = this.newMessageQueue.shift();
        this.appendMessageWithTypingEffect(nextMessage);
      } else if (this.pendingCompletion) {
        // 如果队列为空且等待结束，则完成对话
        this.finishConversation();
      }
    },

    // 使用打字效果追加消息
    appendMessageWithTypingEffect(message) {
      this.typingInProgress = true;

      let index = 0;
      const baseText = this.currentAnswer;
      const messageLength = message.length;

      const typeInterval = setInterval(() => {
        if (index < messageLength) {
          this.currentAnswer = baseText + message.slice(0, ++index);
          this.scrollToBottom();
        } else {
          clearInterval(typeInterval);
          this.typingInProgress = false;

          // 检查是否有更多消息需要显示
          if (this.newMessageQueue && this.newMessageQueue.length > 0) {
            this.showNextMessage();
          } else if (this.pendingCompletion) {
            // 如果队列为空且等待结束，则完成对话
            this.finishConversation();
          }
        }
      }, this.typingSpeed);
    },

    scrollToBottom() {
      this.$nextTick(() => {
        const container = this.$refs.chatContent;
        if (container) {
          container.scrollTop = container.scrollHeight;
        }
      });
    },

    // 切换侧边栏
    toggleSidebar() {
      const oldState = this.sidebarCollapsed;
      this.sidebarCollapsed = !this.sidebarCollapsed;
      console.log(`侧边栏状态: ${oldState} -> ${this.sidebarCollapsed}`);

      // 侧边栏状态变化后，重新调整滚动位置
      this.$nextTick(() => {
        this.scrollToBottom();
        // 发送自定义事件，以便Vue开发工具可以跟踪
        this.$emit('sidebar-toggle', this.sidebarCollapsed);
      });
    },

    // 切换对话
    switchDialogue(id) {
      if (id !== this.dialogueId) {
        this.dialogueId = id;
        this.showWelcome = false; // 切换到已有对话时隐藏欢迎界面
        this.prompt = ""; // 切换对话时清空prompt
        this.loadChatHistory();
      }
    },

    // 创建新对话
    createNewDialogue() {
      createDialogue().then(response => {
        if (response.code === 200 && response.data) {
          this.dialogueId = response.data;
          this.chatMessages = [];
          this.currentAnswer = "";
          this.isTyping = false;
          this.isThisChatOver = true;
          this.showWelcome = true; // 设置showWelcome为true
          this.prompt = ""; // 清空prompt
          this.$message.success("成功创建新对话");
          // 刷新对话列表
          this.loadDialogueList();
        } else {
          this.$message.error("创建对话失败");
        }
      }).catch(error => {
        console.error("创建对话出错:", error);
        this.$message.error("创建对话出错");
      });
    },

    // 加载历史消息
    loadChatHistory() {
      if (!this.dialogueId) return;

      getChatHistory(this.dialogueId).then(response => {
        if (response.code === 200 && response.data) {
          // 转换消息格式
          this.chatMessages = response.data.map(msg => ({
            role: msg.role,
            content: msg.content
          }));

          // 如果有消息历史，隐藏欢迎界面
          if (this.chatMessages.length > 0) {
            this.showWelcome = false;
          }

          this.scrollToBottom();
        }
      }).catch(error => {
        console.error("获取聊天历史失败:", error);
      });
    },

    // 使用快速提问
    useQuickQuestion(question) {
      this.inputMessage = question;
      if (!this.dialogueId) {
        this.createNewDialogue();
        // 等待创建对话完成后再发送消息
        setTimeout(() => {
          if (this.dialogueId) {
            this.sendMessage();
          }
        }, 500);
      } else {
        this.sendMessage();
      }
    },

    // 发送消息
    sendMessage() {
      if (!this.inputMessage.trim() || !this.isThisChatOver) {
        return;
      }

      if (!this.dialogueId) {
        this.createNewDialogue();
        return;
      }

      const message = this.inputMessage;
      this.chatMessages.push({
        role: 'user',
        content: message
      });
      this.inputMessage = "";
      this.isThisChatOver = false;
      this.isTyping = true; // 显示等待状态
      this.currentAnswer = ""; // 清空当前回答
      this.showWelcome = false; // 隐藏欢迎界面
      this.scrollToBottom();

      // 发送消息到服务器，包含提示词
      sendChatMessage({
        dialogueId: this.dialogueId,
        content: message,
        prompt: this.prompt
      }).then(() => {
        // 消息发送成功，等待WebSocket接收回复
        // 刷新剩余次数
        this.loadRemainingCount();
      }).catch(error => {
        console.error("发送消息出错:", error);
        this.$message.error("发送消息失败");
        this.isThisChatOver = true;
        this.isTyping = false;
      });
    },
    // 检查用户登录状态
    checkUserLogin() {
      if (!this.isLoggedIn) {
        this.$modal.alert('请先登录后再使用AI聊天功能', '提示', {
          confirmButtonText: '去登录',
          callback: () => {
            this.$router.push('/login');
          }
        });
      }
    },
    // 加载用户历史对话列表
    loadDialogueList() {
      listDialogues({ pageNum: 1, pageSize: 30 }).then(response => {
        if (response.code === 200 && response.rows) {
          this.dialogueList = response.rows;

          if (response.rows.length > 0 && !this.dialogueId) {
            // 自动加载最近的对话
            this.dialogueId = response.rows[0].dialogueId;
            this.loadChatHistory();
          }
        }
      }).catch(error => {
        console.error("获取对话列表失败:", error);
      });
    },

    // 格式化时间
    formatTime(timestamp) {
      if (!timestamp) return '';

      const date = new Date(timestamp);
      const today = new Date();
      const yesterday = new Date(today);
      yesterday.setDate(yesterday.getDate() - 1);

      // 判断是否是今天
      if (date.toDateString() === today.toDateString()) {
        return '今天 ' + date.getHours().toString().padStart(2, '0') + ':' +
               date.getMinutes().toString().padStart(2, '0');
      }

      // 判断是否是昨天
      if (date.toDateString() === yesterday.toDateString()) {
        return '昨天 ' + date.getHours().toString().padStart(2, '0') + ':' +
               date.getMinutes().toString().padStart(2, '0');
      }

      // 其他日期
      return (date.getMonth() + 1) + '月' + date.getDate() + '日';
    },
    // 处理对话删除
    handleDeleteDialogue(id) {
      if (id === this.dialogueId) {
        this.$message.warning("当前正在进行的对话不能删除");
        return;
      }

      deleteDialogue(id).then(response => {
        if (response.code === 200) {
          this.$message.success("对话删除成功");
          // 刷新对话列表
          this.loadDialogueList();
        } else {
          this.$message.error(response.msg || "删除对话失败");
        }
      }).catch(error => {
        console.error("删除对话出错:", error);
        this.$message.error("删除对话出错");
      });
    },
    // 处理清空所有对话
    handleClearAllDialogues() {
      if (this.dialogueList.length === 0) {
        this.$message.info("没有可清空的对话记录");
        return;
      }

      const nonActiveDialogues = this.dialogueList.filter(item => item.dialogueId !== this.dialogueId);

      if (nonActiveDialogues.length === 0) {
        this.$message.warning("只有当前正在进行的对话，无法清空");
        return;
      }

      // 删除所有非当前活动的对话
      const promises = nonActiveDialogues.map(item =>
        deleteDialogue(item.dialogueId)
      );

      Promise.all(promises)
        .then(() => {
          this.$message.success("对话记录已清空");
          this.loadDialogueList();
        })
        .catch(error => {
          console.error("清空对话记录出错:", error);
          this.$message.error("清空对话记录时出错");
        });
    },
    // 复制消息内容
    copyMessage(content) {
      if (!content) return;

      // 创建一个临时的textarea元素
      const textarea = document.createElement('textarea');

      // 移除HTML标签获取纯文本
      const plainText = content.replace(/<[^>]+>/g, '');

      textarea.value = plainText;
      document.body.appendChild(textarea);
      textarea.select();

      try {
        // 执行复制操作
        const successful = document.execCommand('copy');
        if (successful) {
          this.$message({
            message: "内容已复制到剪贴板",
            type: "success",
            duration: 1500
          });
        } else {
          this.$message.error("复制失败，请手动复制");
        }
      } catch (err) {
        this.$message.error("复制失败: " + err);
      }

      // 移除临时元素
      document.body.removeChild(textarea);
    },
    // 加载剩余聊天次数
    loadRemainingCount() {
      getChatRemainingCount().then(response => {
          this.remainingCount = response.data || 0;
      }).catch(error => {
        console.error("获取剩余聊天次数失败:", error);
      });
    },
    // 设置用户头像
    setUserAvatar() {
      try {
        // 从localStorage或vuex等获取用户信息
        const avatar = this.$store.getters.avatar;
        if (avatar) {
          // 如果用户有自定义头像，则使用用户头像
          // 检查头像地址是否需要添加前缀
          if (avatar.startsWith('http')) {
            this.userAvatar = avatar;
          } else {
            // 可能需要添加服务器前缀
            this.userAvatar = process.env.VUE_APP_BASE_API + avatar;
          }
        } else {
          // 未找到用户头像，使用默认头像
          this.userAvatar = this.defaultAvatar;
        }
      } catch (error) {
        console.error("获取用户头像失败:", error);
        // 出错时使用默认头像
        this.userAvatar = this.defaultAvatar;
      }
    },
    // 切换WebSocket连接方式
    switchConnectionMode() {
      // 此方法已被环境变量配置取代，保留为空以防有地方调用
      this.$message.info("WebSocket连接模式由环境变量控制，请修改环境配置文件后重启应用");
    },
    // 选择常用提示词
    selectCommonPrompt(command) {
      if (command === 'clear') {
        this.prompt = '';
      } else {
        this.prompt = command;
      }
    },
  }
};
</script>

<style scoped>
.app-container {
  height: 100%;
}

.chat-layout {
  display: flex;
  height: calc(100vh - 130px);
  background-color: #f9f9f9;
  box-shadow: 0 2px 12px 0 rgba(0,0,0,.1);
  border-radius: 8px;
  overflow: hidden;
  width: 100%;
  position: relative;
}

/* 聊天历史侧边栏样式 */
.history-sidebar {
  width: 240px;
  min-width: 240px;
  background-color: #fff;
  border-right: 1px solid #eaeaea;
  display: flex;
  flex-direction: column;
  transition: all 0.3s ease;
  flex-shrink: 0;
  z-index: 2;
}

.history-sidebar.collapsed {
  width: 0;
  min-width: 0;
  margin: 0;
  padding: 0;
  border-right: none;
  overflow: hidden;
}

.sidebar-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 15px;
  border-bottom: 1px solid #eaeaea;
}

.sidebar-header-actions {
  display: flex;
  align-items: center;
}

.clear-btn {
  color: #909399;
  margin-right: 8px;
  font-size: 14px;
  opacity: 0.7;
  transition: all 0.3s;
}

.clear-btn:hover {
  color: #f56c6c;
  opacity: 1;
}

.sidebar-new-chat {
  display: flex;
  align-items: center;
  padding: 12px 15px;
  margin: 10px;
  cursor: pointer;
  transition: all 0.3s;
  border: 1px dashed #409EFF;
  border-radius: 8px;
  color: #409EFF;
  background-color: rgba(64, 158, 255, 0.1);
}

.sidebar-new-chat:hover {
  background-color: rgba(64, 158, 255, 0.2);
  box-shadow: 0 2px 8px rgba(64, 158, 255, 0.2);
}

.sidebar-new-chat i {
  font-size: 16px;
  margin-right: 8px;
}

.sidebar-content {
  flex: 1;
  overflow-y: auto;
  padding: 10px;
}

.empty-history {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  color: #909399;
  height: 100px;
}

.empty-history i {
  font-size: 30px;
  margin-bottom: 10px;
}

.history-item {
  padding: 12px;
  border-radius: 8px;
  margin-bottom: 10px;
  cursor: pointer;
  transition: all 0.2s ease;
  border: 1px solid #f0f0f0;
  background-color: #fff;
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.history-item:hover {
  background-color: #f0f9ff;
  box-shadow: 0 2px 8px rgba(0,0,0,0.05);
}

.history-item.active {
  background-color: #ecf5ff;
  color: #409EFF;
  border-color: #b3d8ff;
  box-shadow: 0 2px 8px rgba(64,158,255,0.15);
}

.history-item-content {
  flex: 1;
  overflow: hidden;
}

.history-item-title {
  font-weight: 500;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  margin-bottom: 6px;
  line-height: 1.4;
}

.history-item-time {
  font-size: 12px;
  color: #909399;
}

.history-item-actions {
  margin-left: 10px;
}

.delete-btn {
  color: #f56c6c;
  opacity: 0.7;
  transition: all 0.3s;
}

.delete-btn:hover {
  opacity: 1;
}

/* 主聊天区域样式 */
.chat-container {
  flex: 1;
  display: flex;
  flex-direction: column;
  background-color: #f9f9f9;
  min-width: 0;
  width: 100%;
  z-index: 1;
  transition: all 0.3s ease;
}

.chat-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 10px 20px;
  border-bottom: 1px solid #eaeaea;
  background-color: #fff;
}

.toggle-btn {
  font-size: 18px;
  transition: all 0.3s ease;
  z-index: 3;
}

.toggle-btn:hover {
  color: #409EFF;
}

.chat-content {
  flex: 1;
  overflow-y: auto;
  padding: 20px;
  scroll-behavior: smooth;
  overflow-x: hidden;
  max-width: 100%;
  width: 100%;
}

.welcome-container {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  height: 100%;
}

.welcome-title {
  font-size: 24px;
  font-weight: bold;
  margin-bottom: 10px;
  color: #409EFF;
}

.welcome-tips {
  font-size: 16px;
  color: #606266;
  margin-bottom: 30px;
}

.quick-questions {
  width: 80%;
  max-width: 600px;
}

.quick-title {
  font-size: 16px;
  margin-bottom: 15px;
  color: #606266;
}

.quick-item {
  background-color: #ecf5ff;
  color: #409EFF;
  padding: 12px 15px;
  border-radius: 6px;
  margin-bottom: 10px;
  cursor: pointer;
  transition: all 0.3s;
  box-shadow: 0 2px 6px rgba(0,0,0,0.05);
}

.quick-item:hover {
  background-color: #409EFF;
  color: #fff;
  transform: translateY(-2px);
  box-shadow: 0 4px 8px rgba(0,0,0,0.1);
}

.messages-container {
  display: flex;
  flex-direction: column;
  width: 100%;
  max-width: 100%;
  overflow: hidden;
}

.message {
  display: flex;
  margin-bottom: 20px;
  max-width: 85%;
  animation: fadeIn 0.3s ease;
  position: relative;
  overflow: hidden;
}

@keyframes fadeIn {
  from { opacity: 0; transform: translateY(10px); }
  to { opacity: 1; transform: translateY(0); }
}

.user-message {
  align-self: flex-end;
  flex-direction: row-reverse;
}

.ai-message {
  align-self: flex-start;
}

.message-avatar {
  width: 40px;
  height: 40px;
  margin: 0 10px;
  flex-shrink: 0;
}

.message-avatar img {
  width: 100%;
  height: 100%;
  border-radius: 50%;
  box-shadow: 0 2px 6px rgba(0,0,0,0.1);
}

.message-content {
  padding: 12px 16px;
  border-radius: 6px;
  word-break: break-word;
  overflow-wrap: break-word;
  max-width: calc(100% - 60px);
  width: 100%;
  overflow: hidden;
}

.user-message .message-content {
  background-color: #409EFF;
  color: #fff;
  border-top-right-radius: 0;
  box-shadow: 0 2px 6px rgba(64,158,255,0.2);
}

.ai-message .message-content {
  background-color: #fff;
  color: #303133;
  border-top-left-radius: 0;
  box-shadow: 0 2px 6px rgba(0,0,0,0.08);
  position: relative;
  max-width: 100%;
  word-wrap: break-word;
  overflow: hidden;
}

.ai-message .message-content :deep(img) {
  max-width: 100%;
  height: auto;
}

.ai-message .message-content :deep(pre) {
  background-color: #f6f8fa;
  border-radius: 4px;
  padding: 0;
  margin: 0;
  font-size: 14px;
  box-shadow: none;
  max-width: 100%;
  width: 100%;
  overflow: visible;
}

.ai-message .message-content :deep(code) {
  font-family: 'JetBrains Mono', Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace;
  font-size: 13px;
  line-height: 1.5;
  white-space: pre-wrap;
  word-break: break-word;
}

.ai-message .message-content :deep(:not(pre) > code) {
  padding: 0.2em 0.4em;
  margin: 0;
  font-size: 85%;
  background-color: rgba(27, 31, 35, 0.05);
  border-radius: 3px;
  white-space: normal;
}

.ai-message .message-content :deep(.code-block-wrapper) {
  background-color: #f6f8fa;
  border-radius: 4px;
  margin: 15px 0;
  border: 1px solid #e1e4e8;
  overflow: hidden;
  max-width: 100%;
  width: 100%;
}

.ai-message .message-content :deep(.code-block-header) {
  display: flex;
  justify-content: space-between;
  background-color: #e1e4e8;
  padding: 6px 12px;
  color: #24292e;
  font-size: 12px;
  font-weight: 500;
}

.ai-message .message-content :deep(.code-language) {
  text-transform: uppercase;
  letter-spacing: 0.5px;
}

.ai-message .message-content :deep(.code-copy-btn) {
  background: transparent;
  border: none;
  cursor: pointer;
  color: #0366d6;
  font-size: 12px;
  padding: 0 4px;
}

.ai-message .message-content :deep(.code-copy-btn:hover) {
  text-decoration: underline;
}

.ai-message .message-content :deep(.code-container) {
  position: relative;
  overflow-x: auto;
  max-width: 100%;
  width: 100%;
}

.ai-message .message-content :deep(.hljs) {
  max-width: 100%;
  overflow-x: auto;
  padding: 12px;
  white-space: pre;
  width: 100%;
  box-sizing: border-box;
  font-size: 13px;
}

.ai-message .message-content :deep(pre) {
  margin: 0;
  padding: 0;
  background-color: transparent;
  border-radius: 0;
  box-shadow: none;
  max-width: 100%;
}

.ai-message .message-content :deep(pre code) {
  white-space: pre;
  word-wrap: normal;
  overflow-wrap: normal;
  display: inline-block;
  box-sizing: border-box;
  font-size: 13px;
  tab-size: 2;
  -moz-tab-size: 2;
  width: max-content;
  max-width: none;
}

.typing-indicator {
  display: flex;
  align-items: center;
  justify-content: center;
  height: 20px;
}

.typing-indicator span {
  display: inline-block;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: #606266;
  margin: 0 2px;
  opacity: 0.6;
  animation: typingAnimation 1s infinite ease-in-out;
}

.typing-indicator span:nth-child(1) {
  animation-delay: 0s;
}

.typing-indicator span:nth-child(2) {
  animation-delay: 0.2s;
}

.typing-indicator span:nth-child(3) {
  animation-delay: 0.4s;
}

@keyframes typingAnimation {
  0%, 60%, 100% { transform: translateY(0); }
  30% { transform: translateY(-5px); }
}

.chat-input {
  padding: 15px 20px;
  background-color: #fff;
  border-top: 1px solid #eaeaea;
}

.prompt-input {
  margin-bottom: 10px;
}

.prompt-field {
  width: 100%;
}

.prompt-label {
  color: #606266;
  font-size: 14px;
}

.prompt-help {
  font-size: 13px;
  color: #606266;
}

.prompt-help ul {
  margin-top: 5px;
  padding-left: 20px;
}

.prompt-help li {
  margin-bottom: 5px;
}

.el-dropdown-link {
  cursor: pointer;
  color: #409EFF;
  margin: 0 10px;
}

.el-dropdown-menu {
  max-height: 300px;
  overflow-y: auto;
}

.input-actions {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-top: 10px;
}

.input-tips {
  color: #909399;
  font-size: 12px;
}

.header-actions {
  display: flex;
  align-items: center;
}

.message-actions {
  display: flex;
  justify-content: flex-end;
  margin-top: 8px;
  opacity: 0;
  transition: opacity 0.2s ease;
}

.message-content:hover .message-actions {
  opacity: 1;
}

.copy-btn {
  padding: 4px 8px;
  color: #909399;
  font-size: 14px;
  background-color: rgba(255, 255, 255, 0.8);
  border-radius: 4px;
}

.copy-btn:hover {
  color: #409EFF;
  background-color: #ecf5ff;
}

.remaining-count {
  margin-right: 20px;
  font-size: 14px;
  color: #606266;
  background-color: #f2f6fc;
  padding: 6px 12px;
  border-radius: 16px;
  display: flex;
  align-items: center;
  transition: all 0.3s ease;
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05);
  animation: pulse 2s infinite;
}

.remaining-count i {
  margin-right: 5px;
  font-size: 16px;
  color: #409EFF;
}

.remaining-count span {
  font-weight: bold;
  color: #409EFF;
  margin-left: 4px;
  font-size: 16px;
}

.warning-count {
  background-color: #fdf6ec;
  box-shadow: 0 2px 6px rgba(230, 162, 60, 0.2);
}

.warning-count i,
.warning-count span {
  color: #E6A23C;
}

.danger-count {
  background-color: #fef0f0;
  box-shadow: 0 2px 6px rgba(245, 108, 108, 0.2);
}

.danger-count i,
.danger-count span {
  color: #F56C6C;
}

@keyframes pulse {
  0% {
    transform: scale(1);
  }
  50% {
    transform: scale(1.03);
  }
  100% {
    transform: scale(1);
  }
}

.ai-message .message-content :deep(blockquote) {
  border-left: 3px solid #dfe2e5;
  color: #6a737d;
  padding: 0 1em;
  margin: 0 0 16px;
}

.ai-message .message-content :deep(table) {
  border-collapse: collapse;
  width: 100%;
  margin: 15px 0;
  display: block;
  overflow-x: auto;
}

.ai-message .message-content :deep(th),
.ai-message .message-content :deep(td) {
  border: 1px solid #dfe2e5;
  padding: 6px 13px;
}

.ai-message .message-content :deep(th) {
  background-color: #f6f8fa;
  font-weight: 600;
}

.ai-message .message-content :deep(tr:nth-child(2n)) {
  background-color: #f6f8fa;
}

@media screen and (max-width: 768px) {
  .chat-content {
    max-width: 100vw;
  }
}
</style>
